package org.sherlock.downloader;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

public class DownloadsQueue {
	private static final int CONCURRENT_DOWNLOADS = 5;

	private final LinkedList<Download> queue;
	private final PoolWorker[] threads;

	private int concurrentDownloads;

	public DownloadsQueue() {
		this(CONCURRENT_DOWNLOADS);
	}

	public DownloadsQueue(int concurrentDownloads) {
		this.concurrentDownloads = concurrentDownloads;

		queue = new LinkedList<Download>();
		threads = new PoolWorker[concurrentDownloads];

		for (int i = 0; i < concurrentDownloads; i++) {
			threads[i] = new PoolWorker();
			threads[i].start();
		}
	}

	public void execute(Download download) {
		synchronized (queue) {
			queue.addLast(download);
			queue.notify();
		}
	}

	public int getConcurrentDownloads() {
		return concurrentDownloads;
	}

	public void setConcurrentDownloads(int concurrentDownloads) {
		this.concurrentDownloads = concurrentDownloads;
	}

	public void sortQueue(Comparator<Download> comparator) {
		Collections.sort(queue, comparator);
	}

	private class PoolWorker extends Thread {
		public void run() {
			Runnable runnable;

			while (true) {
				synchronized (queue) {
					while (queue.isEmpty()) {
						try {
							queue.wait();
						} catch (InterruptedException ignored) {
						}
					}
					
					runnable = (Runnable) queue.removeFirst().getFetcher();
				}

				try {
					runnable.run();
				} catch (RuntimeException e) {
				}
			}
		}
	}
}
